package pokpok.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;

import pokpok.domaine.Identifiable;

public class GenericDAO<O extends Identifiable, K> {
	private Class<O> persistentClass;

	@SuppressWarnings("unchecked")
	public GenericDAO() {
		this.persistentClass = (Class<O>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	public PersistenceManager getPM() {
		return PMF.get().getPersistenceManager();
	}

	public O findById(K key) {
		PersistenceManager pm = getPM();
		Transaction tx = pm.currentTransaction();
		try {
			tx.begin();
			O obj = pm.getObjectById(persistentClass, key);
			tx.commit();
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			if (tx.isActive()) {
				tx.rollback();
			}
			pm.close();
		}
	}

	public O save(O object) {
		PersistenceManager pm = getPM();
		Transaction tx = pm.currentTransaction();
		try {
			tx.begin();
			O saved = pm.makePersistent(object);
			tx.commit();
			return saved;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			if (tx.isActive()) {
				tx.rollback();
			}
			pm.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<O> findAll() {
		PersistenceManager pm = getPM();
		Transaction tx = pm.currentTransaction();
		try {
			tx.begin();
			Query query = pm.newQuery(persistentClass);
			List<O> list = (List<O>) query.execute();
			list.size();
			tx.commit();
			return list;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			if (tx.isActive()) {
				tx.rollback();
			}
			pm.close();
		}
	}

	public void delete(O object) {
		PersistenceManager pm = getPM();
		Transaction tx = pm.currentTransaction();
		try {
			tx.begin();
			pm.deletePersistent(pm.getObjectById(persistentClass,
					object.getId()));
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (tx.isActive()) {
				tx.rollback();
			}
			pm.close();
		}
	}

}
